package edu.predatorwars.shared.models;

import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;

import edu.predatorwars.shared.models.Buff;

public class Creature 
{
	public static final int STAT_MAX_HEALTH = 0;
	public static final int STAT_SPEED = 1;
	public static final int STAT_SIGHT = 2;
	public static final int STAT_STRENGTH = 3;
	public static final int STAT_ARMOR = 4;
	public static final int STAT_HEALTH = 5;
	
	public static final int TYPE_GORILLA = 0;
	public static final int TYPE_ELEPHANT = 1;
	public static final int TYPE_SNAKE = 2;
	public static final int TYPE_WOLF = 3;
	public static final int TYPE_BEAR = 4;
	
	private final String name;
	private final int type;
	
	private final Map<Integer,Float> baseStats;
	private final Collection<Buff> buffs;
	
	public Creature(int creatureType,Map<Integer,Float> baseStats)
	{
		this.type = creatureType;
		switch (creatureType) {
		case TYPE_GORILLA: name = "gorilla"; break;
		case TYPE_ELEPHANT: name = "elephant"; break;
		case TYPE_SNAKE: name = "snake"; break;
		case TYPE_WOLF: name = "wolf"; break;
		case TYPE_BEAR: name = "bear"; break;
		default: name = "";
		}
		
		this.baseStats = baseStats;
		this.buffs = new HashSet<Buff>();
	}
	
	/**
	 * Get the name of this creature.
	 * @return
	 */
	public String getName()
	{
		return name;
	}
	
	
	/**
	 * Get the integer type of the creature 
	 */
	
	public int getCreatureType() {
		return type;
	}
	
	/**
	 * Sets the health of this creature.
	 * @param health
	 */
	public void setHealth(float health)
	{	
		baseStats.put(STAT_HEALTH, health);
	}
	/**
	 * Returns the base value of the given stat for this creature (Not including any buffs)
	 * @param stat
	 * @return
	 */
	public float getBaseStat(int stat)
	{
		return baseStats.get(stat);
	}
	
	/**
	 * Returns a map of each stat string to its value.
	 * @param stat
	 * @return
	 */
	public Map<Integer,Float>  getBaseStats()
	{
		return new HashMap<Integer,Float> (baseStats);
	}
	
	/**
	 * Returns the value of the given stat for this creature, including any buffs
	 * @param stat
	 * @return
	 */
	public float getStat(int stat)
	{
		float value = getBaseStat(stat);
		if(stat != STAT_HEALTH)
			for(Buff buff: buffs)
				if(buff.getStat()==stat)
					value += buff.getValue();
		return value;
	}
	
	/**
	 * Add a new buff to the creature, should only be called by the Game Engine.
	 * @param buff
	 */
	public void addBuff(Buff buff)
	{
		buffs.add(buff);
	}
	
	
	/**
	 * Remove a buff from the creature, should only be called by the Game Engine.
	 * @param buff
	 */
	public void removeBuff(Buff buff)
	{
		buffs.remove(buff);
	}
	
	/**
	 * Get a list of all the buffs on the creature;
	 * @return
	 */
	public Collection<Buff> getBuffs()
	{
		return Collections.unmodifiableCollection(buffs);
	}
	
	/**
	 * Returns true iff this creature has more then 0 health.
	 * @return
	 */
	public boolean isAlive()
	{
		return getStat(STAT_HEALTH) >0;
	}
}
